package com.spm.librarianmanagersystem.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.spm.librarianmanagersystem.mapper.*;
import com.spm.librarianmanagersystem.pojo.BookBookId;
import com.spm.librarianmanagersystem.pojo.Borrow;
import com.spm.librarianmanagersystem.pojo.Fine;
import com.spm.librarianmanagersystem.pojo.Librarian;
import com.spm.librarianmanagersystem.pojo.Member;
import com.spm.librarianmanagersystem.service.UserInfoService;
import org.apache.ibatis.transaction.TransactionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service("UserInfoService")
public class UserInfoServiceImpl implements UserInfoService {
    @Autowired
    private MemberMapper mm;
    @Autowired
    private LibrarianMapper lm;
    @Autowired
    private BorrowMapper bm;
    @Autowired
    private FineMapper fm;
    @Autowired
    private ReservationMapper rm;
    @Autowired
    private BookMapper bookMapper;
    @Autowired
    private BookBookIdMapper bbim;

    @Override
    public JSONObject getUserProfileDetail(String currentUserId) {
        System.out.println( currentUserId);
        Member memberByID = mm.getMemberByID(currentUserId);
        System.out.println( memberByID);
        Integer borrowNum = bm.getBorrowNum(memberByID.getUserId());
        JSONObject obj = new JSONObject();
        obj.put("user_id", memberByID.getUserId());
        obj.put("id", memberByID.getId());
        obj.put("avatar", memberByID.getAvatar());
        obj.put("name", memberByID.getName());
        obj.put("gender", memberByID.getGender());
        obj.put("position", memberByID.getPosition());
        obj.put("email", memberByID.getEmail());
        obj.put("phone_number", memberByID.getPhoneNumber());
        obj.put("borrowings", borrowNum);
        obj.put("max_borrowing", memberByID.getUpperLimits());
        obj.put("reputation_score",memberByID.getReputationScore());
        return obj;
    }

    @Override
    public JSONObject getAdminProfileDetail(String adminId) {
        System.out.println(adminId);
        Librarian memberByID = lm.getLibrarianByID(adminId);
        System.out.println(memberByID);
        Integer borrowNum = bm.getBorrowNum(memberByID.getUserId());
        JSONObject obj = new JSONObject();
        obj.put("user_id", memberByID.getUserId());
        obj.put("id", memberByID.getId());
        obj.put("avatar", memberByID.getAvatar());
        obj.put("name", memberByID.getName());
        obj.put("gender", memberByID.getGender());
        obj.put("email", memberByID.getEmail());
        obj.put("phone_number", memberByID.getPhoneNumber());
        obj.put("borrowings", borrowNum);
        obj.put("max_borrowing", memberByID.getUpperLimits());
        return obj;
    }

    @Override
    public JSONObject getReaderDashboardInfo(String currentUserId) {
        Integer userID = mm.getUserIDByID(currentUserId);
        Integer borrowNum = bm.getBorrowNum(userID);
        Borrow lastReturned = bm.getLastReturned(userID);
        String bookISBN = null;
        String bookName = null;
        Double totalFineAmount = fm.getTotalFineAmount(userID);
        if (lastReturned != null) {
            bookISBN = lastReturned.getISBN();
            bookName = bookMapper.getABook(bookISBN).getBookName();
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("borrowing", borrowNum);
        jsonObject.put("last_returned_book", bookISBN);
        jsonObject.put("last_returned_book_name", bookName);
        jsonObject.put("fine_amount", totalFineAmount);
        return jsonObject;
    }

    @Override
    public JSONObject getAdminDashboardInfo() {
        Integer readerNum = mm.getReaderNum();
        Integer bookNum = bookMapper.getBookNum();
        List<BookBookId> bookCopys = bbim.getBookCopys();
        List<BookBookId> lostBooks = bbim.getLostBooks();
        List<BookBookId> damagedBooks = bbim.getDamagedBooks();
        int bookCopyNum = bookCopys.size();
        int lostBookNum = lostBooks.size();
        int damagedBookNum = damagedBooks.size();
        Integer borrowNumAll = bm.getBorrowNumAll();
        Integer fineNum = fm.getFineNum();
        Double fineCollected = fm.getFineCollected();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("total_readers", readerNum);
        jsonObject.put("total_books", bookNum);
        jsonObject.put("total_book_copys", bookCopyNum);
        jsonObject.put("total_borrowings", borrowNumAll);
        jsonObject.put("total_fine", fineNum);
        jsonObject.put("total_lost_books", lostBookNum);
        jsonObject.put("total_damaged_books", damagedBookNum);
        jsonObject.put("total_fine_collected", fineCollected);
        return jsonObject;
    }

    @Override
    public Member editUserProfile(JSONObject object) {
        Boolean aBoolean = mm.updateUserProfile(object.getInteger("user_id"),
                object.getString("id"),
                object.getString("password"),
                object.getString("name"),
                object.getInteger("gender"),
                object.getInteger("position"),
                object.getString("email"),
                object.getString("phone_number"));
        if (aBoolean) {
            return mm.getMemberByID(object.getString("id"));
        }
        return null;
    }

    @Override
    @Transactional
    public Boolean userClose(String currentUserId) {
        List<Borrow> borrowingList = bm.getBorrowingList(currentUserId);
        if (borrowingList.size() != 0)
            throw new TransactionException("还有未还的书籍");
        List<Fine> fineList = fm.getFineList(currentUserId);
        if (fineList.size() != 0)
            throw new TransactionException("还有未缴纳的罚款");
        Integer userID = mm.getUserIDByID(currentUserId);
        rm.deleteAllByUserID(userID);
        fm.deleteAllByUserID(userID);
        bm.deleteAllByUserID(userID);
        return mm.deleteMyself(currentUserId);
    }

    public boolean updateReputation(String currentUserId, Integer change) {
        Member memberByID = mm.getMemberByID(currentUserId);
        Integer user_id = memberByID.getUserId();
        int newScore = memberByID.getReputationScore() + change;
        mm.updateReputation(user_id, newScore);
        return true;
    }
}
